---
title: Theme - Flowbite React
description: Learn how to customize the appearance of Flowbite React components using the theming system
---

Flowbite React provides a flexible theming system that allows you to customize the appearance of components. The system is built on top of Tailwind CSS and supports multiple levels of customization.

## Component-Level Customization

The simplest way to customize a component is by using the `className` prop, which allows you to override or extend the default styles:

```tsx
import { Button } from "flowbite-react";

function App() {
  return <Button className="bg-red-500 hover:bg-red-600">Custom Button</Button>;
}
```

## Theme Provider

For application-wide customization, use the `ThemeProvider` component. The `createTheme` helper provides TypeScript and Tailwind CSS IntelliSense support:

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const customTheme = createTheme({
  button: {
    color: {
      primary: "bg-red-500 hover:bg-red-600",
      secondary: "bg-blue-500 hover:bg-blue-600",
    },
    size: {
      lg: "px-6 py-3 text-lg",
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={customTheme}>
      <Button color="primary">Red Button</Button>
      <Button color="secondary" size="lg">
        Large Blue Button
      </Button>
    </ThemeProvider>
  );
}
```

## Theme Resolution and Inheritance

The theming system follows this resolution order:

1. Component-specific `clearTheme` prop
2. Component-specific `theme` prop
3. Nearest parent `ThemeProvider` theme
4. Default component theme

When using nested `ThemeProvider` components, the following rules apply:

Unless `root={true}` is specified:

- Child providers inherit and merge all theme values from their parent
- They only override the specific values they define
- Parent values for undefined properties are preserved

When `root={true}` is specified:

- The theme provider ignores all parent theme values
- No merging occurs with parent themes
- Only the specified theme and default theme values are used
- This affects all theme-related props (`theme`, `clearTheme`, `applyTheme`) and component props

## Nested Themes

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const mainTheme = createTheme({
  button: {
    color: {
      primary: "bg-blue-500 hover:bg-blue-600",
    },
    size: {
      lg: "px-6 py-3",
    },
  },
});

const sectionTheme = createTheme({
  button: {
    color: {
      primary: "bg-green-500 hover:bg-green-600",
      // size.lg from mainTheme is preserved
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={mainTheme}>
      <Button size="lg">Blue Large Button</Button>
      <ThemeProvider theme={sectionTheme}>
        {/* Inherits size.lg from mainTheme */}
        <Button size="lg">Green Large Button</Button>
      </ThemeProvider>
    </ThemeProvider>
  );
}
```

### Preventing Theme Inheritance

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const mainTheme = createTheme({
  button: {
    color: {
      primary: "bg-blue-500 hover:bg-blue-600",
    },
    size: {
      lg: "px-6 py-3",
    },
  },
});

const isolatedTheme = createTheme({
  button: {
    color: {
      primary: "bg-green-500 hover:bg-green-600",
    },
    // No size definitions
  },
});

function App() {
  return (
    <ThemeProvider theme={mainTheme}>
      <Button size="lg">Large Blue Button</Button>

      {/* root={true} prevents merging with mainTheme */}
      <ThemeProvider theme={isolatedTheme} root>
        <Button size="lg">
          {/* size="lg" will use default theme since isolatedTheme
              doesn't define sizes and parent theme is ignored */}
        </Button>
      </ThemeProvider>
    </ThemeProvider>
  );
}
```

### Theme Merging Strategy

The theme system uses the following merging strategy:

1. **Props Merging**: Component props from parent and child `ThemeProvider`s are deep merged
2. **Theme Merging**: Theme values are merged using [tailwind-merge](https://www.npmjs.com/package/tailwind-merge) for intelligent Tailwind CSS class handling
3. **Clear Theme Merging**: `clearTheme` values are deep merged between providers
4. **Apply Theme Merging**: `applyTheme` configurations are deep merged between providers

The use of `tailwind-merge` ensures:

- Automatic conflict resolution between Tailwind CSS classes
- Support for both Tailwind CSS v3 and v4 (automatically detected)
- Proper handling of complex class combinations
- Efficient merging without duplicate utilities

For example:

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const baseTheme = createTheme({
  button: {
    base: "rounded-lg shadow-md",
    color: {
      primary: "bg-blue-500 text-white",
    },
  },
});

const customTheme = createTheme({
  button: {
    base: "border-2",
    color: {
      primary: "bg-red-500",
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={baseTheme}>
      {/* Merges themes: rounded-lg shadow-md border-2 */}
      <Button theme={customTheme.button}>Merged Styles</Button>

      {/* Replaces base completely: only border-2 remains */}
      <Button theme={customTheme.button} applyTheme={{ base: "replace" }}>
        Replaced Base Style
      </Button>

      {/* Replaces color completely: loses text-white */}
      <Button theme={customTheme.button} applyTheme={{ color: { primary: "replace" } }}>
        Replaced Color
      </Button>
    </ThemeProvider>
  );
}
```

## Theme Modification Tools

The combination of `theme`, `clearTheme`, and `applyTheme` props provides granular control over component styling. Here are examples showing different levels of customization:

### Component Level Control

```tsx
import { Card, createTheme } from "flowbite-react";

const cardTheme = createTheme({
  card: {
    root: {
      base: "rounded-xl bg-white shadow-md",
      children: "space-y-4 p-6",
    },
    img: {
      base: "rounded-t-xl",
      horizontal: "h-full w-full rounded-l-xl",
    },
  },
});

function App() {
  return (
    <>
      {/* Basic theme override */}
      <Card theme={cardTheme.card}>Basic Theme Override</Card>

      {/* Clear specific nested properties */}
      <Card
        theme={cardTheme.card}
        clearTheme={{
          root: { children: true }, // Clear only padding and spacing
          img: { horizontal: true }, // Clear horizontal image styles
        }}
      >
        Selective Clearing
      </Card>

      {/* Control how new styles are applied */}
      <Card
        theme={cardTheme.card}
        applyTheme={{
          root: { base: "replace" }, // Replace entire base styles
          img: { base: "merge" }, // Merge with existing image styles
        }}
      >
        Controlled Style Application
      </Card>

      {/* Combining all three props */}
      <Card theme={cardTheme.card} clearTheme={{ root: { children: true } }} applyTheme={{ img: { base: "replace" } }}>
        Complex Style Control
      </Card>
    </>
  );
}
```

### Nested Component Control

```tsx
import { createTheme, Navbar, NavbarCollapse, NavbarLink, ThemeProvider } from "flowbite-react";

const navTheme = createTheme({
  navbar: {
    root: {
      base: "bg-white shadow-lg",
    },
    collapse: {
      base: "w-full md:block md:w-auto",
      list: "mt-4 flex flex-col md:mt-0 md:flex-row md:space-x-8",
    },
    link: {
      base: "block px-3 py-2",
      active: {
        on: "text-blue-600",
        off: "text-gray-900",
      },
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={navTheme}>
      <Navbar>
        {/* Control collapse styles */}
        <NavbarCollapse
          clearTheme={{ list: true }} // Remove default list styles
          applyTheme={{ base: "replace" }} // Replace base styles
        >
          {/* Control individual link styles */}
          <NavbarLink
            href="#"
            active
            theme={{
              base: "font-medium",
              active: {
                on: "text-green-600", // Override active state
              },
            }}
            applyTheme={{
              active: { on: "merge" }, // Merge active state styles
            }}
          >
            Custom Link
          </NavbarLink>
        </NavbarCollapse>
      </Navbar>
    </ThemeProvider>
  );
}
```

### Form Components Control

```tsx
import { createTheme, Label, TextInput } from "flowbite-react";

const formTheme = createTheme({
  label: {
    root: {
      base: "text-sm font-medium",
      disabled: "opacity-50",
      colors: {
        default: "text-gray-900",
        error: "text-red-700",
      },
    },
  },
  textInput: {
    base: "block w-full",
    field: {
      base: "rounded-lg border",
      input: {
        base: "px-3 py-2",
        sizes: {
          sm: "text-sm",
          md: "text-base",
        },
        colors: {
          gray: "border-gray-300 bg-gray-50",
          error: "border-red-500 bg-red-50",
        },
      },
    },
  },
});

function App() {
  return (
    <form>
      {/* Label with error state */}
      <Label
        theme={formTheme.label}
        color="error"
        clearTheme={{
          root: { disabled: true }, // Remove disabled styles
        }}
      >
        Email
      </Label>

      {/* Input with custom styling */}
      <TextInput
        theme={formTheme.textInput}
        color="error"
        size="sm"
        applyTheme={{
          field: {
            input: {
              colors: { error: "replace" }, // Replace error styles
              sizes: { sm: "merge" }, // Merge size styles
            },
          },
        }}
      />

      {/* Combining multiple controls */}
      <TextInput
        theme={formTheme.textInput}
        clearTheme={{
          field: {
            input: { sizes: true }, // Remove all size variations
          },
        }}
        applyTheme={{
          base: "merge", // Merge base styles
          field: { base: "replace" }, // Replace field base styles
        }}
      />
    </form>
  );
}
```

These examples demonstrate how to:

- Use nested theme properties for precise control
- Clear specific style categories while preserving others
- Control how new styles are merged or replaced
- Combine multiple theme controls for complex customization
- Handle component-specific theme variations
- Manage state-dependent styles (active, disabled, etc.)

## Clearing Theme Values

The `clearTheme` prop allows you to selectively or completely remove theme values, reverting them to their default styles. When a theme value is cleared, it's set to an empty string.

### Basic Usage

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const theme = createTheme({
  button: {
    color: {
      primary: "bg-red-500 hover:bg-red-600",
    },
    base: "rounded-lg",
  },
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Button>Red Rounded Button</Button>
      {/* Clear specific theme property */}
      <Button clearTheme={{ color: true }}>Default Color, Still Rounded</Button>
      {/* Clear all button theme values */}
      <Button clearTheme>Completely Default Button</Button>
    </ThemeProvider>
  );
}
```

### Selective Clearing

You can clear specific nested properties while keeping others:

```tsx
import { Card, createTheme, ThemeProvider } from "flowbite-react";

const theme = createTheme({
  card: {
    root: {
      base: "rounded-xl shadow-lg",
      children: "space-y-4 p-6",
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Card>Regular Card</Card>
      <Card clearTheme={{ root: { children: true } }}>
        {/* Keeps rounded-xl and shadow-lg, but clears padding and spacing */}
      </Card>
    </ThemeProvider>
  );
}
```

## Applying Theme Values

The `applyTheme` prop provides fine-grained control over how theme values are merged. It supports two modes:

- `"merge"` (default): Combines the new theme values with existing ones
- `"replace"`: Completely replaces existing theme values

### Merging vs Replacing

```tsx
import { Button, createTheme, ThemeProvider } from "flowbite-react";

const baseTheme = createTheme({
  button: {
    base: "rounded-lg shadow-md",
    color: {
      primary: "bg-blue-500 text-white",
    },
  },
});

const customTheme = createTheme({
  button: {
    base: "border-2",
    color: {
      primary: "bg-red-500",
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={baseTheme}>
      {/* Merges themes: rounded-lg shadow-md border-2 */}
      <Button theme={customTheme.button}>Merged Styles</Button>

      {/* Replaces base completely: only border-2 remains */}
      <Button theme={customTheme.button} applyTheme={{ base: "replace" }}>
        Replaced Base Style
      </Button>

      {/* Replaces color completely: loses text-white */}
      <Button theme={customTheme.button} applyTheme={{ color: { primary: "replace" } }}>
        Replaced Color
      </Button>
    </ThemeProvider>
  );
}
```

### Inheritance Control

The `applyTheme` prop is particularly useful when working with nested components:

```tsx
import { createTheme, Navbar, NavbarCollapse, NavbarLink, ThemeProvider } from "flowbite-react";

const theme = createTheme({
  navbar: {
    root: {
      base: "bg-white shadow-lg",
    },
    collapse: {
      base: "w-full md:block md:w-auto",
      list: "mt-4 flex flex-col md:mt-0 md:flex-row md:space-x-8",
    },
  },
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Navbar>
        <NavbarCollapse
          applyTheme={{
            list: "replace", // Replace entire list styles
          }}
        >
          <NavbarLink href="#">Custom Layout</NavbarLink>
        </NavbarCollapse>
      </Navbar>
    </ThemeProvider>
  );
}
```

### Theme Resolution Order

When both `clearTheme` and `applyTheme` are used, the resolution follows this order:

1. Apply `clearTheme` to remove specified values
2. Apply component-specific `theme` prop
3. Apply `applyTheme` rules to control how new values are merged
4. Inherit from parent `ThemeProvider` (unless `root={true}`)
5. Fall back to default component theme

This system provides complete control over theme inheritance and application while maintaining a predictable behavior.

## Provider-Level Props

The `ThemeProvider` component accepts a `props` prop that allows you to set default props for all components within its scope. These props are merged with any component-specific props, with component props taking precedence:

```tsx
import { Button, ThemeProvider } from "flowbite-react";

function App() {
  return (
    <ThemeProvider
      props={{
        // Set default props for all buttons
        button: {
          color: "success",
          size: "lg",
        },
      }}
    >
      {/* Will be large and green */}
      <Button>Inherits Provider Props</Button>

      {/* Will be large and red (color prop overrides provider) */}
      <Button color="error">Overrides Color Prop</Button>

      {/* Nested providers merge props by default */}
      <ThemeProvider
        props={{
          button: {
            size: "sm", // Override size while keeping color from parent
          },
        }}
      >
        {/* Will be small and green */}
        <Button>Inherits Merged Props</Button>
      </ThemeProvider>

      {/* root={true} prevents props inheritance */}
      <ThemeProvider
        root
        props={{
          button: {
            size: "sm",
          },
        }}
      >
        {/* Will be small with default color */}
        <Button>Independent Props</Button>
      </ThemeProvider>
    </ThemeProvider>
  );
}
```

Props are resolved in the following order:

1. Component-specific props
2. Nearest parent `ThemeProvider` props
3. Default component props

Like themes, provider props are deep merged between parent and child providers unless `root={true}` is specified.

## Component-Specific Theme

You can also apply a custom theme to a specific component instance using the `theme` prop:

```tsx
import { Button, createTheme } from "flowbite-react";

const buttonTheme = createTheme({
  button: {
    color: {
      custom: "bg-purple-500 text-white hover:bg-purple-600",
    },
  },
}).button;

function App() {
  return (
    <Button theme={buttonTheme} color="custom">
      Purple Button
    </Button>
  );
}
```

## Type Safety and IntelliSense

The `createTheme` helper ensures type safety and enables Tailwind CSS IntelliSense in your IDE:

```tsx
import { createTheme } from "flowbite-react";

// Full theme customization
const theme = createTheme({
  button: {
    color: {
      primary: "bg-blue-500 hover:bg-blue-600", // ✓ Tailwind CSS IntelliSense
      custom: 123, // ✗ Type error: expected string
    },
  },
});

// Single component theme
const buttonTheme = createTheme({
  button: {
    size: {
      xl: "px-8 py-4 text-xl", // ✓ Tailwind CSS IntelliSense
    },
  },
}).button;
```

This helps catch errors early and provides better development experience with auto-completion for Tailwind CSS classes.

For information on how to create your own themeable components that work with this system, see the [Creating Custom Components](/docs/customize/custom-components) guide.
